import datetime

def enum(*sequential, **named):
    enums = dict(zip(sequential, range(len(sequential))), **named)
    return type('Enum', (), enums)

def abstract(func):
    def wrapper(self, *args,**kwargs):
        raise NotImplementedError(func.__name__)
    return wrapper

def return_policy(base_class=object):
    def wrapper(func):
        def func_w_arg(*args, **kargs):
            retval = func(*args,**kargs)
            if not issubclass(retval.__class__, base_class):
                raise AttributeError('return value is not subclass of ' + base_class.__name__)
            return retval
        return func_w_arg
    return wrapper
    

class AbstractObject(object):
    def __init__(self):            
        for field in self.get_fields():
            super(AbstractObject,self).__setattr__(field[0],'')
        
    def __setattr__(self,name,value):
        found = False
        for field in self.get_fields():
            if name == field[0] and value is not None:
                found = True
                field_val = None
                field_type = field[2]
                try:
                    field_val = field_type(value)
                except TypeError:
                    if value == '':
                        field_val = datetime.date.today()
                    else:
                        date_val = value.split('-')
                        if len(date_val) == 3:
                            field_val = datetime.date(int(date_val[0])
                                                     ,int(date_val[1])
                                                     ,int(date_val[2]))
                except ValueError:
                    field_val = None

                if field_val is None:
                       raise AttributeError
                       
                super(AbstractObject,self).__setattr__(name,field_val)
        if not found:
            super(AbstractObject,self).__setattr__(name,value)
        
    @abstract
    def get_fields(self):
        pass

